import Tablero
import Damas
import HUnit
import Maybe

-- evaluar t para correr todos los tests
t = runTestTT allTests

allTests = test [ 
	"triviales" ~: testsTriviales
	,"tablero"   ~: testTablero
	,"mover"     ~: testMover
--	"movimientoPosibles" ~: tMovimientosPosibles
    ,"Ganador"   ~: testGanador
    ,"ValuacionDamas" ~: testValuacionDamas
	
	]



testTablero = test [
-- Ejercicio 1
   contenido a_1 vacio  ~=?  Nothing,
   
-- Ejercicio 2
    
    contenido a_1 ( poner _b (a_1) vacio )                   ~=? Just _b,   -- contenido de poner es la ficha que puse
    contenido a_1 ( poner _b (a_1) ( poner _b (a_1) vacio))  ~=? Just _b,   -- poner es idempotente
    contenido a_1 (sacar (a_1) ( poner _b (a_1) vacio))      ~=? Nothing,   -- contenido de sacar es Nothing la unica ficha del tablero es vacio
    sacar (a_1)( vacio)                                      ~=? vacio      -- sacar de vacio es vacio
    

    ]	




testMover = test [
-- Ejercicio 3
    -- MOVER
        -- mover TL | TR | BR | BL mueve efectivamente en esa direccion ( blancas para "arriba", negras para abajo )
        -- Que la ficha se mueva en la dirección correcta, si no es una reina.
         -- Blanca
          fromJust (contenido  c_6 (tablero (fromJust ( mover (M d_5 TL) (J Blanca ( poner (_b) d_5 vacio )))))) ~=? _b
         ,fromJust (contenido  e_6 (tablero (fromJust ( mover (M d_5 TR) (J Blanca ( poner (_b) d_5 vacio )))))) ~=? _b
         -- Negra
         ,fromJust (contenido  e_4 (tablero (fromJust ( mover (M d_5 BR) (J Negra ( poner (_n) d_5 vacio )))))) ~=? _n
         ,fromJust (contenido  c_4 (tablero (fromJust ( mover (M d_5 BL) (J Negra ( poner (_n) d_5 vacio )))))) ~=? _n
  
    --  reinas para todos lados
         ,fromJust (contenido  c_6 (tablero (fromJust ( mover (M d_5 TL) (J Blanca ( poner (_B) d_5 vacio )))))) ~=? _B
         ,fromJust (contenido  e_6 (tablero (fromJust ( mover (M d_5 TR) (J Blanca ( poner (_B) d_5 vacio )))))) ~=? _B
         ,fromJust (contenido  e_4 (tablero (fromJust ( mover (M d_5 BR) (J Blanca ( poner (_B) d_5 vacio )))))) ~=? _B
         ,fromJust (contenido  c_4 (tablero (fromJust ( mover (M d_5 BL) (J Blanca ( poner (_B) d_5 vacio )))))) ~=? _B

         -- No anda si muevo para el sentido contrario "a mi color"
         ,isNothing (  mover (M d_5 BR) (J Blanca ( poner (_b) d_5 vacio ))) ~=? True
         ,isNothing (  mover (M d_5 BL) (J Blanca ( poner (_b) d_5 vacio ))) ~=? True

         ,isNothing (  mover (M d_5 TR) (J Negra ( poner (_n) d_5 vacio ))) ~=? True
         ,isNothing (  mover (M d_5 TL) (J Negra ( poner (_n) d_5 vacio ))) ~=? True
  
         
        -- Que las casillas de origen y destino no caigan fuera
            
            -- Origen Fruta (hay ficha pero la pos esta mal)
                -- letra fruta
                  ,isNothing (  mover (M ('z',5) TR) (J Blanca ( poner (_b) ('z',5) vacio ))) ~=? True
                -- numero fruta
                  ,isNothing (  mover (M ('c',50) TR) (J Blanca ( poner (_b) ('c',50) vacio ))) ~=? True
                -- los 2 fruta  
                  ,isNothing (  mover (M ('z',50) TR) (J Blanca ( poner (_b) ('z',50) vacio ))) ~=? True
                  
        -- Destino Fruta (hay ficha pero la pos destino esta mal)              
              ,isNothing (  mover (M h_8 TR) (J Blanca ( poner (_b) h_8 vacio ))) ~=? True
          
        -- Que haya una ficha en la casilla de origen. 
              ,isNothing (  mover (M d_5 TR) (J Blanca ( vacio ))) ~=? True
        
        -- Que el color de la ficha movida coincida con el color del jugador al que le toca mover. 
        --( mueven las Negras pero intento mover una blanca )
              ,isNothing (  mover (M d_5 TR) (J Negra ( poner (_b) d_5 vacio ))) ~=? True
        --( simetrico con el otro caso )
              ,isNothing (  mover (M d_5 TR) (J Blanca ( poner (_n) d_5 vacio ))) ~=? True

        -- Que la casilla de destino esté libre.
             ,isNothing (  mover (M d_5 BL) (J Negra ( poner (_n) c_4 (poner (_n) d_5 vacio )))) ~=? True 
               
        --En caso de tratarse de una captura, que la casilla intermedia contenga una ficha del color del adversario.
        -- si cuando muevo hay una ficha oponente en el destino, la capturo y hago un salto, 
        -- en d 5 habia una reina y despues de mover no hay nada
           ,isNothing ( contenido d_5 (tablero(fromJust( mover (M c_4 TR) (J Blanca ( poner (_N ) d_5(poner (_b) c_4 vacio))))))) ~=? True


    ]

--testMovimientosPosibles = test [
-- Ejercicio 4
    -- que efectivamente sean exactamente los movimientos Posibles ( ni mas ni menos)
--    ]   
--    movimientosPosibles(J Blanca vacio) ~=? movimientosPosibles(J Blanca vacio)-- []--(((M (d_6 TR),j1):((M (e_6 TL),j2)) 
--j0 = (J Blanca(poner (_b) d_5 vacio))
--j1 = (J Negra (poner (_b) e_6 vacio))
--j2 = (J Negra (poner (_b) c_6 vacio))


--testPodar = test[
           
    -- arbol con una reina arbol infinito ( habra opciones para moverme )
--    podar 1 movimientosPosibles (J Blanca(poner (_N) d_5(poner (_b) a_2 vacio)))
--]movimientosPosibles(J Blanca(poner (Simple Negra) ('d',5)(poner (Simple Blanca) ('a',2) vacio)))



testGanador = test [
    --si adversario no tiene mas fichas, gano yo
    ganador(J Blanca(poner (_b) d_5 vacio)) ~=? Just Blanca,
    ganador(J Negra(poner (_n) d_5 vacio)) ~=? Just Negra
    
    --si no tengo movimientos posibles, gana adversario   ( el adversario debe tener fichas )
    ,ganador(J Blanca(poner (_n) d_5(poner (_b) h_8 vacio))) ~=? Just Negra
   
    ]


testValuacionDamas = test[
   -- testeamos la cuentita
    valuacionDamas (J Blanca(poner (_b) d_5 vacio)) ~=? 1 
    ,valuacionDamas (J Blanca(poner (_n) d_5 vacio)) ~=? -1
    
    -- una ficha misma cantidad de fichas
    ,valuacionDamas (J Blanca(poner (_n) d_5(poner (_b) a_2 vacio))) ~=? 0.0

    -- las negras tienen una reina mas, pero es el turno de las blancas el valor es negativo ( el truncate es para poder comparar )
      ,truncate (valuacionDamas (J Blanca(poner (_N) d_5(poner (_b) a_2 vacio)))*100) ~=? truncate (-100/3)

    -- las negras tienen una reina mas, como es el turno de las negras tienen  ( el truncate es para poder comparar )
    ,truncate (valuacionDamas (J Negra (poner (_N) d_5(poner (_b) a_2 vacio)))*100) ~=? truncate (100/3)
    
    
    
    ]


testsTriviales = test [
	1 ~=? 1,
	2 ~=? 2,
	[1,2] ~=? [1,2],
	[1,2] ~~? [2,1]
	]
	
	
	
	
	
	
	
	
	
	

-- idem ~=? pero sin importar el orden
(~~?) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Test
expected ~~? actual = (sort expected) ~=? (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

(~~) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Bool
expected ~~ actual = (sort expected) == (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

-- constantes para que los tests sean más legibles		





_n = Simple Negra
_N = Reina Negra
_b = Simple Blanca
_B = Reina Blanca
a_1 = ('a',1::Int)
b_1 = ('b',1::Int)
c_1 = ('c',1::Int)
d_1 = ('d',1::Int)
e_1 = ('e',1::Int)
f_1 = ('f',1::Int)
g_1 = ('g',1::Int)
h_1 = ('h',1::Int)
a_2 = ('a',2::Int)
b_2 = ('b',2::Int)
c_2 = ('c',2::Int)
d_2 = ('d',2::Int)
e_2 = ('e',2::Int)
f_2 = ('f',2::Int)
g_2 = ('g',2::Int)
h_2 = ('h',2::Int)

a_3 = ('a',3::Int)
b_3 = ('b',3::Int)
c_3 = ('c',3::Int)
d_3 = ('d',3::Int)
e_3 = ('e',3::Int)
f_3 = ('f',3::Int)
g_3 = ('g',3::Int)
h_3 = ('h',3::Int)

a_4 = ('a',4::Int)
b_4 = ('b',4::Int)
c_4 = ('c',4::Int)
d_4 = ('d',4::Int)
e_4 = ('e',4::Int)
f_4 = ('f',4::Int)
g_4 = ('g',4::Int)
h_4 = ('h',4::Int)

a_5 = ('a',5::Int)
b_5 = ('b',5::Int)
c_5 = ('c',5::Int)
d_5 = ('d',5::Int)
e_5 = ('e',5::Int)
f_5 = ('f',5::Int)
g_5 = ('g',5::Int)
h_5 = ('h',5::Int)

a_6 = ('a',6::Int)
b_6 = ('b',6::Int)
c_6 = ('c',6::Int)
d_6 = ('d',6::Int)
e_6 = ('e',6::Int)
f_6 = ('f',6::Int)
g_6 = ('g',6::Int)
h_6 = ('h',6::Int)

a_7 = ('a',7::Int)
b_7 = ('b',7::Int)
c_7 = ('c',7::Int)
d_7 = ('d',7::Int)
e_7 = ('e',7::Int)
f_7 = ('f',7::Int)
g_7 = ('g',7::Int)
h_7 = ('h',7::Int)

a_8 = ('a',8::Int)
b_8 = ('b',8::Int)
c_8 = ('c',8::Int)
d_8 = ('d',8::Int)
e_8 = ('e',8::Int)
f_8 = ('f',8::Int)
g_8 = ('g',8::Int)
h_8 = ('h',8::Int)
